﻿/*****************************************************************************
 
 Use of Ext is under the Ext JS license, for more information, 
 please visit http://extjs.com/products/license.php page. 
  
 You should confirm that you have read, understood and accept ethical criteria listed. 
 If not, see <http://www.mvcnext.com/license/>.
  
 Version: 1.0.0.0
 Website: http://www.mvcnext.com/
 
 Copyright (c) Yoganand R. All rights reserved.
 For continued development and updates, visit http://yogsbreath.net
 
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Web.UI;

namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// Base class for form fields that provides default event handling, sizing, value handling and other functionality.
    /// </summary>
    [Description("Base class for form fields that provides default event handling, sizing, value handling and other functionality.")]
    public class Field : ExtBoxComponent  
    {
        public override List<ScriptReference> GetScriptReferences()
        {
            return base.GetScriptReferences();
        }

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {
            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.form.Field";

            String[] properties = new String[]{
                "autoCreate", "clearCls", "fieldClass", "fieldLabel", "focusClass", "hideLabel", "invalidClass", "invalidText", "itemCls", "name",
                "labelSeparator", "labelStyle", "msgFx", "readOnly", "tabIndex", "validateOnBlur", "validateDelay", "validationEvent", "value" 
            };

            Type component = typeof(Field);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'Field.{0}'", property));

                Object value = i.GetValue(this, null);               

                //get the default value attribute
                if (value == null)
                {
                    // Gets the attributes for the property.
                    System.ComponentModel.AttributeCollection attributes =
                       TypeDescriptor.GetProperties(this)[property].Attributes;

                    /* get the default value by retrieving the DefaultValueAttribute 
                       from the AttributeCollection. */
                    DefaultValueAttribute defaultAttribute =
                       (DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)];

                    if (defaultAttribute != null)
                        value = defaultAttribute.Value;
                }

                if (value == null)
                {
                    continue;
                }

                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property, String.Format("'{0}'", value));
            }                        

            return list;
        }

        #region Public Properties

        /// <summary>
        /// A DomHelper element spec (defaults to {tag: 'input', type: 'text', size: '20', autocomplete: 'off'}).
        /// </summary>
        [Browsable(false)]
        [Description("A DomHelper element spec (defaults to {tag: 'input', type: 'text', size: '20', autocomplete: 'off'}).")]
        public String autoCreate { get; set; }

        /// <summary>
        /// The CSS class used to provide field clearing (defaults to 'x-form-clear-left').
        /// </summary>
        [Description("The CSS class used to provide field clearing (defaults to 'x-form-clear-left').")]
        public String clearCls { get; set; }

        /// <summary>
        /// The default CSS class for the field (defaults to 'x-form-field').
        /// </summary>
        [Description("The default CSS class for the field (defaults to 'x-form-field').")]
        public String fieldClass { get; set; }

        /// <summary>
        /// The label text to display next to this field (defaults to '').
        /// </summary>
        [Description("The label text to display next to this field (defaults to '').")]
        public String fieldLabel { get; set; }

        /// <summary>
        /// The CSS class to use when the field receives focus (defaults to 'x-form-focus').
        /// </summary>
        [Description("The CSS class to use when the field receives focus (defaults to 'x-form-focus').")]
        public String focusClass { get; set; }

        /// <summary>
        /// True to completely hide the label element (defaults to false).
        /// </summary>
        [Description("True to completely hide the label element (defaults to false).")]
        public Boolean? hideLabel { get; set; }

        /// <summary>
        /// The CSS class to use when marking a field invalid (defaults to 'x-form-invalid').
        /// </summary>
        [Description("The CSS class to use when marking a field invalid (defaults to 'x-form-invalid').")]
        public String invalidClass { get; set; }

        /// <summary>
        /// The error text to use when marking a field invalid and no message is provided (defaults to 'The value in this field is invalid').
        /// </summary>
        [Description("The error text to use when marking a field invalid and no message is provided (defaults to 'The value in this field is invalid').")]
        public String invalidText { get; set; }

        /// <summary>
        /// An additional CSS class to apply to this field (defaults to the contentContainer's itemCls value if set, or '').
        /// </summary>
        [Description("An additional CSS class to apply to this field (defaults to the contentContainer's itemCls value if set, or '').")]
        public String itemCls { get; set; }

        /// <summary>
        /// The standard separator to display after the text of each form label (defaults is a colon ':'). To display no separator for this field's label specify empty string ''.
        /// </summary>
        [DefaultValue(":")]
        [Description("The standard separator to display after the text of each form label (defaults is a colon ':'). To display no separator for this field's label specify empty string ''.")]
        public String labelSeparator { get; set; }

        /// <summary>
        /// A CSS style specification to apply directly to this field's label (defaults to the contentContainer's labelStyle value if set, or ''). For example, labelStyle: 'font-weight:bold;'.
        /// </summary>
        [Description("A CSS style specification to apply directly to this field's label (defaults to the contentContainer's labelStyle value if set, or ''). For example, labelStyle: 'font-weight:bold;'.")]
        public String labelStyle { get; set; }

        /// <summary>
        /// EXPERIMENTAL The effect used when displaying a validation message under the field (defaults to 'normal').
        /// </summary>
        [DefaultValue("normal")]
        [Description("EXPERIMENTAL The effect used when displaying a validation message under the field (defaults to 'normal').")]
        public String msgFx { get; set; }

        /// <summary>
        /// True to mark the field as readOnly in HTML (defaults to false) -- Note: this only sets the element's readOnly DOM attribute.
        /// </summary>
        [Description("True to mark the field as readOnly in HTML (defaults to false) -- Note: this only sets the element's readOnly DOM attribute.")]
        public Boolean? readOnly { get; set; }

        /// <summary>
        /// The tabIndex for this field. Note this only applies to fields that are rendered, not those which are built via applyTo (defaults to undefined).
        /// </summary>
        [DefaultValue((short)0)]
        [Description("The tabIndex for this field. Note this only applies to fields that are rendered, not those which are built via applyTo (defaults to undefined).")]
        public short? tabIndex { get; set; }

        /// <summary>
        /// Whether the field should validate when it loses focus (defaults to true).
        /// </summary>
        [DefaultValue(true)]
        [Description("Whether the field should validate when it loses focus (defaults to true).")]
        public Boolean? validateOnBlur { get; set; }

        /// <summary>
        /// The length of time in milliseconds after user input begins until validation is initiated (defaults to 250).
        /// </summary>
        [DefaultValue(250)]
        [Description("The length of time in milliseconds after user input begins until validation is initiated (defaults to 250).")]
        public int? validateDelay { get; set; }

        /// <summary>
        /// The event that should initiate field validation. Set to false to disable automatic validation (defaults to 'keyup').
        /// </summary>
        [Description("The event that should initiate field validation. Set to false to disable automatic validation (defaults to 'keyup').")]
        public String validationEvent { get; set; }

        /// <summary>
        /// The Text value to initialize this field with.
        /// </summary>
        [DefaultValue("")]
        [Description("The Text value to initialize this field with.")]
        public String value { get; set; }

        /// <summary>
        /// A name of this field.
        /// </summary>
        [Description("A name of this field.")]
        public String name { get; set; }

        ///// <summary>
        ///// A ID of this field.
        ///// </summary>
        //[Description("A ID of this field.")]
        //public override String ID { get; set; }


        #endregion
    }
}
